package com.shuma.auth.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shuma.auth.entity.dto.Account;
import com.shuma.auth.mapper.AccountMapper;
import com.shuma.auth.mapper.OrdersMapper;
import com.shuma.auth.model.dto.ExchangeDataDto;
import com.shuma.auth.model.dto.ExchangeWayDataDto;
import com.shuma.auth.model.dto.SaleTop20DataDto;
import com.shuma.auth.model.po.Orders;
import com.shuma.auth.model.to.ExchangeDataAndDateTo;
import com.shuma.auth.model.to.SaleAndCategoryTo;
import com.shuma.auth.model.to.SaleAndExchangeWayTo;
import com.shuma.auth.service.OrdersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author lele
 */
@Slf4j
@Service
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    @Resource
    OrdersMapper ordersMapper;

    @Resource
    AccountMapper accountMapper;

    @Override
    public ExchangeDataDto exchangeDataAnalyze(LocalDate begin, LocalDate end,Long id) {

        if(begin.plusDays(60).isBefore(end)){
            throw new RuntimeException("选择时间应不高于60天");
        }
        //当前集合用于存放从begin到end范围内的每天的日期
        List<LocalDate> dateList = new ArrayList<>();
        dateList.add(begin);

        while (!begin.equals(end)) {
            //日期计算，计算指定日期的后一天对应的日期
            begin = begin.plusDays(1);
            dateList.add(begin);
        }
        //存放每天的兑换量
        List<Integer> exchangeDataList = new ArrayList<>();
        for (LocalDate date : dateList) {
            //查询date日期对应的营业额数据，营业额是指：状态为“已完成”的订单金额合计
            LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
            LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);

            // select sum(amount) from orders where order_time > beginTime and order_time < endTime and state = 4
            Map map = new HashMap();
            map.put("begin", beginTime);
            map.put("end", endTime);
            map.put("state", 4);//订单已完成
            Integer exchangeData = ordersMapper.sumByMap(map);

            exchangeData = exchangeData == null ? 0 : exchangeData;

            exchangeDataList.add(exchangeData);
        }

        ExchangeDataDto exchangeDataDto = new ExchangeDataDto();
        exchangeDataDto.setExchangeDataList(exchangeDataList);
        exchangeDataDto.setTimeList(dateList);

        //封装返回结果
        return exchangeDataDto;
    }

    @Override
    public SaleTop20DataDto saleTop20DataAnalyze(LocalDate beginTime, LocalDate endTime,Long id) {
        //判断是否为管理员
        if(!isAdmin(id)){
            return null;
        }
        Map map = new HashMap();
        map.put("begin", beginTime);
        map.put("end", endTime);
        map.put("state", 4);//订单已完成
        map.put("limitNum",20);
        List<SaleAndCategoryTo> saleAndCategoryTos = ordersMapper.saleAndCategory(map);
        //销量集合
        List<Integer> saleList = new ArrayList<>();
        //分类集合
        List<String> categoryNameList = new ArrayList<>();
        //分配数据
        for (SaleAndCategoryTo saleAndCategoryTo : saleAndCategoryTos) {
            saleList.add(saleAndCategoryTo.getSale());
            categoryNameList.add(saleAndCategoryTo.getCategoryName());
        }
        //构造返回值
        SaleTop20DataDto saleTop20DataDto = new SaleTop20DataDto();
        saleTop20DataDto.setSaleList(saleList);
        saleTop20DataDto.setCategoriesDataList(categoryNameList);
        return saleTop20DataDto;
    }

    @Override
    public ExchangeWayDataDto exchangeWayDataAnalyze(LocalDate beginTime, LocalDate endTime,Long id) {
        //判断是否为管理员
        if(!isAdmin(id)){
            return null;
        }
        if(beginTime.plusDays(60).isBefore(endTime)){
            throw new RuntimeException("选择时间应不高于60天");
        }
        Map map = new HashMap();
        map.put("begin", beginTime);
        map.put("end", endTime);
        map.put("state", 4);//订单已完成
        //数据统计
        List<SaleAndExchangeWayTo> saleAndExchangeWayTos = ordersMapper.saleAndExchangeWay(map);
        //销量集合
        List<Integer> saleList = new ArrayList<>();
        //价格类型集合
        List<Integer> priceTypeList = new ArrayList<>();
        //赋值
        for (SaleAndExchangeWayTo saleAndExchangeWayTo : saleAndExchangeWayTos) {
            saleList.add(saleAndExchangeWayTo.getSale());
            priceTypeList.add(saleAndExchangeWayTo.getPriceType());
        }
        //构造返回值
        ExchangeWayDataDto exchangeWayDataDto = new ExchangeWayDataDto();
        exchangeWayDataDto.setPriceTypeList(priceTypeList);
        exchangeWayDataDto.setSaleList(saleList);
        return exchangeWayDataDto;
    }

    /**
     * sql效率低
     * @param beginTime
     * @param endTime
     * @return
     */
    public ExchangeDataDto exchangeDataAnalyze1(LocalDate beginTime, LocalDate endTime,Long id) {
        //判断是否为管理员
        if(!isAdmin(id)){
            return null;
        }
        Map map = new HashMap();
        map.put("begin", beginTime);
        map.put("end", endTime);
        map.put("state", 4);//订单已完成
        List<ExchangeDataAndDateTo> exchangeDataAndDateTos = ordersMapper.sumByMap1(map);

        //当前集合用于存放从begin到end范围内的每天的日期
        List<LocalDate> dateList = new ArrayList<>();

        //当前集合用于存放从begin到end范围内的每天的兑换量
        List<Integer> exchangeDataList = new ArrayList<>();
        for (ExchangeDataAndDateTo exchangeDataAndDateTo : exchangeDataAndDateTos) {
            dateList.add(exchangeDataAndDateTo.getDate());
            exchangeDataList.add(exchangeDataAndDateTo.getExchangeData());
        }

        ExchangeDataDto exchangeDataDto = new ExchangeDataDto();
        exchangeDataDto.setExchangeDataList(exchangeDataList);
        exchangeDataDto.setTimeList(dateList);

        //封装返回结果
        return exchangeDataDto;
}
    private boolean isAdmin(Long id){
        Account account = accountMapper.selectById(id);
        if(account==null){
            return false;
        }
        if(account.getRoleId()!=1){
            return false;
        }
        return true;
    }
}
